#include "Lora.h"
#include "example.h"

uint8_t BufferSize = BUFFER_SIZE;

ModulationParams_t modulationParams={
    .PacketType                  = PACKET_TYPE_LORA,
    .Params.LoRa.SpreadingFactor = LORA_SF5,
    .Params.LoRa.Bandwidth       = LORA_BW_1600,
    .Params.LoRa.CodingRate      = LORA_CR_LI_4_7
};

PacketParams_t packetParams={
    .PacketType                      = PACKET_TYPE_LORA,
    .Params.LoRa.PreambleLength      = 12,
    .Params.LoRa.HeaderType          = LORA_PACKET_VARIABLE_LENGTH,
    .Params.LoRa.PayloadLength       = BUFFER_SIZE,
    .Params.LoRa.CrcMode             = LORA_CRC_ON,
    .Params.LoRa.InvertIQ            = LORA_IQ_NORMAL
};
PacketStatus_t      packetStatus;
uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;
uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
bool                rxdone = false;
bool                txdone = false;
bool                txtimeout=false;
bool                rxtimeout=false;
//********************************************************
// 回调函数
//********************************************************
void OnTxDone( void )
{
  txdone = true;
}
void OnRxDone( void )
{
  rxdone = true; 
}
void OnTxTimeout( void )
{
  txtimeout = true; 
}
void OnRxTimeout( void )
{
  rxtimeout = true; 
}
void OnRxError(  IrqErrorCode_t errCode )
{
  rxtimeout = true; 
}

RadioCallbacks_t Callbacks =
{
    &OnTxDone,        // txDone
    &OnRxDone,        // rxDone
    NULL,             // syncWordDone
    NULL,             // headerDone
    &OnTxTimeout,     // txTimeout
    &OnRxTimeout,     // rxTimeout
    &OnRxError,       // rxError
    NULL,             // rangingDone
    NULL,             // cadDone
};

//********************************************************
// 初始化
//********************************************************
bool isMaster = true;
void sx1280_int(void)
{
    uint32_t pclk_freq=0;

    PERIPHERAL_ENABLE(SPI, 0);
    DMAC_DisableSyncRequest(SPI_TX_DMA_REQ(SPI0));
    DMAC_DisableSyncRequest(SPI_RX_DMA_REQ(SPI0));
    pclk_freq = SYS_GetPclkFreq();
    SPI_SclkDivTypeDef spi_sclk_div = pclk_freq > 240 ? SPI_CTRL_SCLK_DIV32 : pclk_freq > 120 ? SPI_CTRL_SCLK_DIV8 : SPI_CTRL_SCLK_DIV16;
    SPI_Init(SPI0, spi_sclk_div);

    UTIL_IdleUs(500000);                //500ms  let DC/DC power ramp up
    Radio.Init( &Callbacks );
    Radio.SetRegulatorMode( USE_DCDC ); // Can also be set in LDO mode but consume more power
    
    Radio.SetStandby( STDBY_RC );
    Radio.SetPacketType( modulationParams.PacketType );
    Radio.SetModulationParams( &modulationParams );
    Radio.WriteRegister(0x925,0x1E);
    Radio.SetPacketParams( &packetParams );
    Radio.SetRfFrequency(RF_FREQUENCY);           //灯频率
    Radio.SetBufferBaseAddresses( 0x00, 0x00 );   //接收
    Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_02_US );
    SX1280SetInterruptMode( );
}
//********************************************************
// 
// 
// 
//********************************************************
void paraConfig(uint8_t length)
{
    packetParams.Params.LoRa.PayloadLength = length;
    Radio.SetStandby( STDBY_RC );
    Radio.SetPacketType( modulationParams.PacketType );
    Radio.SetModulationParams( &modulationParams );
    Radio.WriteRegister(0x925,0x1E);
    Radio.SetPacketParams( &packetParams );
    Radio.SetRfFrequency(RF_FREQUENCY);           //灯频率
    Radio.SetBufferBaseAddresses( 0x00, 0x00 ); //接收
    Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_02_US );
}

//********************************************************
// transmit(uint8_t *, uint8_t, uint8_t)
// 功能：发送
// 返回：0 成功   1失败
//********************************************************
uint8_t rf_transmit(uint8_t *data, uint8_t length,  uint16_t timeout_ms)
{
    GPIO_SetHigh(RADIO_PA_GPIO_Port,RADIO_PA_Pin);          //发送
    GPIO_SetLow(RADIO_LNA_GPIO_Port, RADIO_LNA_Pin);        //接收
    paraConfig(length);
    txdone = false;
    txtimeout=false;
    Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
    Radio.SendPayload( data, length, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, timeout_ms } );
                                                            //发送超时
    while((txdone==false)&&(txtimeout==false))
    {
    }
    if(txdone)
    {
        return 0;                                          //成功
    }
    else
    {
        return 1;                                          //超时
    }   
}

//********************************************************
// receive(uint8_t *, uint8_t)
// 功能：接收
// 返回：接收数据长度
//********************************************************
uint8_t rf_receive(uint8_t *data, uint16_t timeout_ms)
{
    uint8_t  length=0;
    GPIO_SetLow(RADIO_PA_GPIO_Port,RADIO_PA_Pin);         //发送
    GPIO_SetHigh(RADIO_LNA_GPIO_Port, RADIO_LNA_Pin);     //接收
    paraConfig(BUFFER_SIZE);
    rxdone = false;
    rxtimeout=false;
    Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
    Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, timeout_ms } );
    while((rxdone==false)&&(rxtimeout==false))
    {
    }
    
    if(rxdone)
    {
        Radio.GetPayload( data, &length, BUFFER_SIZE );
        return length;                                      //成功
    }
    else
    {
        memset(data,0,3);                                  //擦除缓存，最少擦除帧头+长度+指令号
        return 0;                                          //收到0字节
    }   
}
